package cc.yaomm.common.basic.aspect;

import cc.yaomm.common.basic.constant.DefaultConstant;
import cc.yaomm.common.basic.lang.bo.RequestLogBO;
import cc.yaomm.common.basic.util.RequestUtils;
import com.alibaba.fastjson.JSON;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.util.Optional;

/**
 * <p>@Description : 记录请求日志和请求日志</p>
 * <p>@Author : QiLin.Xing </p>
 * <p>@Date : 2019/2/2 9:00 </p>
 */
@Aspect
public class RequestLogAspect {

    private static final Logger LOGGER = LoggerFactory.getLogger(RequestLogAspect.class);

    @Pointcut("@within(org.springframework.web.bind.annotation.RestController) || @within(org.springframework.stereotype.Controller)")
    public void pointCut() {
    }

    @AfterThrowing(value = "pointCut()", throwing = "ex")
    public void afterThrowingMethod(Exception ex) {
        RequestLogBO requestLog = this.getRequestLog();
        requestLog.setResponse(ex.getLocalizedMessage());
        LOGGER.error(requestLog.getUrl() + " | " + JSON.toJSONString(requestLog));
    }

    @AfterReturning(returning = "result", pointcut = "pointCut()")
    public void doAfterReturning(Object result) {
        RequestLogBO requestLogBo = this.getRequestLog();
        //requestLogBo.setResponse(result);
        LOGGER.info(requestLogBo.getUrl() + " | " + JSON.toJSONString(requestLogBo));
    }

    /**
     * <p>@Description : 获取请求日志</p>
     * <p>@Author : QiLin.Xing </p>
     * <p>@Date : 2019/2/2 9:49 </p>
     */
    private RequestLogBO getRequestLog() {
        HttpServletRequest httpServletRequest = RequestUtils.getRequest();
        RequestLogBO requestLog = new RequestLogBO();
        requestLog.setParamsMap(httpServletRequest.getParameterMap());
        requestLog.setUserId(String.valueOf(httpServletRequest.getHeader(DefaultConstant.REQUEST_UID)));
        String requestBody = RequestUtils.getRequestBody(httpServletRequest);
        requestLog.setRequestBody(Optional.ofNullable(requestBody).orElse(requestBody));
        requestLog.setUrl(httpServletRequest.getRequestURI());
        requestLog.setMethod(httpServletRequest.getMethod());
        Object startTimeObj = httpServletRequest.getHeader(DefaultConstant.REQUEST_START_TIME);
        long execTime = startTimeObj == null ? 0 : System.currentTimeMillis() - Long.valueOf(startTimeObj.toString());
        requestLog.setExecTime(execTime + "ms");
        requestLog.setIp(RequestUtils.getIpAddr(httpServletRequest));
        return requestLog;
    }
}
